package com.geen.tuoke.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.http.SslError;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.RelativeLayout;
import androidx.annotation.RequiresApi;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

/***
 * 自定义WebView
 * @author youtui
 */
public class KmWebView extends RelativeLayout {
    private static final String AGENT_ANDROID = "Finance_Android";
    private WebView mWebView;
    private WebSettings mWebSettings;
    private Context mContext;

    public KmWebView(Context context) {
        super(context);
        init(context, null, 0, 0);
    }

    public KmWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0, 0);
    }

    public KmWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public KmWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr, defStyleRes);
    }

    public WebView getWebView() {
        return mWebView;
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        this.mContext = context;
        //WebView内存泄漏处理方案
        setConfigCallback((WindowManager) context.getSystemService(Context.WINDOW_SERVICE));
        mWebView = new WebView(context);
        this.addView(mWebView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        mWebSettings = mWebView.getSettings();
        mWebSettings.setJavaScriptEnabled(true);
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);    //设置Js脚本是否允许自动打开弹窗
        //     mWebSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);//设置WebView底层的布局算法
//        1.NARROW_COLUMNS：可能的话使所有列的宽度不超过屏幕宽度
//        2.NORMAL：正常显示不做任何渲染
//        3.SINGLE_COLUMN：把所有内容放大webview等宽的一列中
        mWebSettings.setUseWideViewPort(true);  //设置WebView是否使用viewport
        mWebSettings.setLoadWithOverviewMode(true); //设置WebView是否使用预览模式加载界面。
        mWebSettings.setSupportZoom(true);// 允许放大缩小
        mWebSettings.setBuiltInZoomControls(true);// 显示放大缩小按钮
        mWebSettings.setDisplayZoomControls(false);// api 11以上                                                                          `
        mWebSettings.setSupportMultipleWindows(false);   //设置WebView是否支持多屏窗口
        mWebSettings.setDomStorageEnabled(true);// 支持html DOM storage API
        String userAgent = mWebSettings.getUserAgentString();

        Log.e("userAgent",userAgent);
        this.getSettings().setUserAgentString(userAgent + " " + AGENT_ANDROID);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
    }

    /**
     * 有些新闻源网页设置了这个会加载失败,所以单独弄出来
     */
    public void setSetting() {
        mWebSettings.setUserAgentString("Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; Droid Build/ESD20) AppleWebKit/530.17 (KHTML, like Gecko) " +
                "Version/4.0 Mobile Safari/530.17");  //改了头部 UserAgent 才可以播放Twitter内置Video
    }

    private static Field sConfigCallback;

    static {
        try {
            sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
            sConfigCallback.setAccessible(true);
        } catch (Exception e) {
            // ignored
        }

    }

    private void setConfigCallback(WindowManager windowManager) {
        try {
            Field field = WebView.class.getDeclaredField("mWebViewCore");
            field = field.getType().getDeclaredField("mBrowserFrame");
            field = field.getType().getDeclaredField("sConfigCallback");
            field.setAccessible(true);
            Object configCallback = field.get(null);

            if (null == configCallback) {
                return;
            }

            field = field.getType().getDeclaredField("mWindowManager");
            field.setAccessible(true);
            field.set(configCallback, windowManager);
        } catch (Exception e) {
        }
    }

    public WebSettings getSettings() {
        return mWebView.getSettings();
    }

    @SuppressLint("JavascriptInterface")
    public void addJavascriptInterface(Object object, String name) {
        mWebView.addJavascriptInterface(object, name);
    }

    public void removeJavascriptInterface(String name) {
        mWebView.removeJavascriptInterface(name);
    }

    private WebViewClient mWebViewClient;

    public void setWebViewClient(WebViewClient client) {
        if (client == null) {
            return;
        }
        mWebViewClient = client;
        mWebView.setWebViewClient(new MyWebViewClient(this));
    }

    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (mWebViewClient != null) {
            return mWebViewClient.shouldOverrideUrlLoading(view, url);
        }
        return true;
    }

    public void onPageFinished(WebView view, String url) {
        if (mWebViewClient != null) {
            mWebViewClient.onPageFinished(view, url);
        }
    }

    public void loadUrl(String url) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        if (mWebView != null) {
            mWebView.loadUrl(url);
        }
    }

    public void loadData(String data, String mimeType, String encoding) {
        if (mWebView == null) {
            return;
        }
        mWebView.loadData(data, mimeType, encoding);
    }


    private class MyWebViewClient extends WebViewClient {

        private WeakReference<KmWebView> webViewRef;

        public MyWebViewClient(KmWebView kmWebView) {
            webViewRef = new WeakReference<>(kmWebView);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (webViewRef != null && webViewRef.get() != null) {
                return webViewRef.get().shouldOverrideUrlLoading(view, url);
            }
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (webViewRef != null && webViewRef.get() != null) {
                webViewRef.get().onPageFinished(view, url);
                return;
            }
            super.onPageFinished(view, url);
        }


        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            super.onReceivedSslError(view, handler, error);
        }

        public void setWebChromeClient(WebChromeClient client) {
            mWebView.setWebChromeClient(client);
        }

        private void loadCompat() {
            //尝试解决 WebView内容重叠问题
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mWebView.clearView();
            } else {
                mWebView.loadUrl("about:blank");
            }
        }

        public void loadUrlCompat(String url) {
            loadCompat();
            loadUrl(url);
        }

        public void loadUrl(String url) {
            if (TextUtils.isEmpty(url)) {
                return;
            }
            if (mWebView != null) {
                mWebView.loadUrl(url);
            }
        }

        public void loadDataCompat(String data, String mimeType, String encoding) {
            loadCompat();
            loadData(data, mimeType, encoding);
        }

        public void loadData(String data, String mimeType, String encoding) {
            if (mWebView == null) {
                return;
            }
            mWebView.loadData(data, mimeType, encoding);
        }

        public void loadDataWithBaseURLCompat(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
            loadCompat();
            loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
        }

        public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
            mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
        }

        public void stopLoading() {
            if (mWebView == null) {
                return;
            }
            mWebView.stopLoading();
        }

        public void reload() {
            if (mWebView == null) {
                return;
            }
            mWebView.reload();
        }

        public boolean canGoBack() {
            if (mWebView == null) {
                return false;
            }
            return mWebView.canGoBack();
        }

        public void goBack() {
            if (mWebView == null) {
                return;
            }
            mWebView.goBack();
        }

        public boolean canGoForward() {
            if (mWebView == null) {
                return false;
            }
            return mWebView.canGoForward();
        }

        public void goForward() {
            if (mWebView == null) {
                return;
            }
            mWebView.goForward();
        }

        public boolean canGoBackOrForward(int steps) {
            return mWebView.canGoBackOrForward(steps);
        }

        public void goBackOrForward(int steps) {
            mWebView.goBackOrForward(steps);
        }

        public void onPause() {
            mWebView.onPause();
        }

        public void onResume() {
            mWebView.onResume();
        }

        public void destroy() {

            if (mWebView == null) {
                return;
            }

            try {
                if (sConfigCallback != null) {
                    sConfigCallback.set(null, null);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            setConfigCallback(null);
            stopLoading();
            mWebViewClient = null;
            mWebView.setTag(null);
            mWebView.removeAllViews();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
            removeAllViews();
        }
    }
}